import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { OverflowModule } from '../overflow/overflow.module';
import { TagItem } from './interface';
import { TagModule } from './tag.module';

@Component({
  template: `
  <lv-tag [(ngModel)]='data' [lvTagTemplate]='tagTpl' lvShowClearAll></lv-tag>
  <ng-template #tagTpl let-item let-index=index>
    <div lv-overflow>tag: index:{{index}}, label: {{item.label}}</div>
  </ng-template>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestTagComponent {
  data: TagItem[];

  constructor() { }

  ngOnInit() {
    this.initData();
  }

  initData() {
    this.data = this.initTag(10);
  }

  initTag(length: number = 10) {
    return Array.from({ length }).map((item, key) => ({
      label: `Tag${key + 1}`,
      removable: true,
    }));
  }
}

describe('TagComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [TestTagComponent],
        imports: [
          CommonModule,
          TagModule,
          FormsModule,
          OverflowModule,
          NoopAnimationsModule
        ],
        teardown: { destroyAfterEach: true },
      }).compileComponents();
    })
  );

  describe('render', () => {
    let component: TestTagComponent;
    let fixture: ComponentFixture<TestTagComponent>;
    const renderComp = fakeAsync(para => {
      for (const [key, value] of Object.entries(para)) {
        component[key] = value;
      }
      fixture.detectChanges();
      tick(500);
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();
      tick(1500);
    });

    beforeEach(fakeAsync(() => {
      fixture = TestBed.createComponent(TestTagComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
      tick(500);
    }));

    it('basic', () => {
      renderComp({});
    });
  });

  describe('function', () => {
    let fixture: ComponentFixture<TestTagComponent>;
    const detectChange = () => {
      fixture.detectChanges();
      tick(500);
      fixture.detectChanges();
      tick(500);
      fixture.detectChanges();
      tick(500);
    };

    beforeEach(fakeAsync(() => {
      fixture = TestBed.createComponent(TestTagComponent);
      detectChange();
    }));

    it('remove', fakeAsync(() => {
      const getTags = () => document.querySelectorAll('.lv-tag-item') as NodeListOf<HTMLElement>;
      const tags = getTags();
      tags[tags.length - 1].querySelector('i').dispatchEvent(new Event('click'));
      detectChange();
      expect(getTags().length).toBe(9);
      expect(fixture).toMatchSnapshot();
      getTags()[0].querySelector('i').dispatchEvent(new Event('click'));
      detectChange();
      expect(getTags().length).toBe(8);
      expect(fixture).toMatchSnapshot();
      getTags()[5].querySelector('i').dispatchEvent(new Event('click'));
      detectChange();
      expect(getTags().length).toBe(7);
      expect(fixture).toMatchSnapshot();
      document.querySelector('.lv-tag-clear').dispatchEvent(new Event('click'));
      detectChange();
      expect(getTags().length).toBe(0);
      expect(fixture).toMatchSnapshot();
    }));
  });
});
